package com.lz.sports.bean

import android.os.Parcel
import android.os.Parcelable
import androidx.databinding.ObservableBoolean
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.PrimaryKey
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonSerializationContext
import com.google.gson.JsonSerializer
import com.lz.library.extension.APP
import com.lz.library.extension.resString
import com.lz.sports.LogUtils
import com.lz.sports.R
import java.lang.reflect.Type

//最终考试成绩表, 也为考生与项目中间表, 一个项目只有一个成绩
@Entity(tableName = "ExamResult")
class ExamResult() : Parcelable {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "examResultId")
    var id: Int = 0

    //考生ID
    @ColumnInfo(name = "examineeId")
    var examineeId: Int = 0

    //考生ID
    @ColumnInfo(name = "projectId")
    var projectId: Int = 0

    //项目名称
    @ColumnInfo(name = "projectName")
    var projectName: String = ""

    //考试计划ID
    @ColumnInfo(name = "examPlanId")
    var examPlanId: Int = 0

    //检录考区ID
    @ColumnInfo(name = "examAreaId")
    var examAreaId: Int = 0

    //检录的考点ID
    @ColumnInfo(name = "examSiteId")
    var examSiteId: Int = 0

    //检录状态, -1未检录
    @ColumnInfo(name = "inspectStatus")
    var inspectStatus = -1

    //考试次数
    @ColumnInfo(name = "examCount")
    var examCount = 0

    //是否缺考 0是
    @ColumnInfo(name = "lackStatus")
    var lackStatus: Int = -1

    //最终成绩分数, -1代表没考
    @ColumnInfo(name = "score")
    var score: Int = -1

    //成绩确认时间
    @ColumnInfo(name = "sureTime")
    var sureTime: Long = 0L

    //上传状态
    @ColumnInfo(name = "uploadStatus")
    var uploadStatus: Int = -1

    //缺考状态是否上传
    @ColumnInfo(name = "lackUploadStatus")
    var lackUploadStatus: Int = -1

    //照片上传状态
    @ColumnInfo(name = "photoUploadStatus")
    var photoUploadStatus: Int = -1

    @Ignore
    var examinee: Examinee? = null

    //该考生下的所有检录数据
    @Ignore
    var inspectList: List<ExamInspect>? = null

    //是否选中
    @Ignore
    var isSelected = ObservableBoolean(false)

    fun isLack(): Boolean = lackStatus == 0

    fun hasInspected(): Boolean = inspectStatus != -1

    fun setLackState() {
        this.lackStatus = 0
    }

    fun saveResult(inspect: ExamInspect) {
        examCount++
        score = score.coerceAtLeast(inspect.score)
    }

    //成绩确认
    fun sure(sureTime: Long, score: Int) {
        this.sureTime = sureTime
        this.score = score
        this.uploadStatus = -1
    }

    //更改选择状态
    fun changeSelected() {
        LogUtils.i("set select ${isSelected.get()}")
        isSelected.set(!isSelected.get())
    }

    //是否已经考试
    fun hasExamined(): Boolean = score >= 0

    fun uploadStatusStrRes(): Int = if (uploadStatus != -1) R.string.manager_upload_s else R.string.manager_upload_un

    fun inspectStatusStrRes(): Int = if (inspectStatus != -1) R.string.manager_checked else R.string.manager_check_un

    //名字拼接
    fun nameStr(): String {
        val stu = examinee ?: return ""
        val sex = if (stu.isMale()) R.string.male else R.string.female
        return APP.getString(R.string.manager_info, stu.studentName, stu.examineesNo, sex.resString())
    }

    //考试状态成绩
    fun examStatus(): String {
        if (isLack()) return R.string.manager_exam_lack.resString()
        if (hasExamined()) return APP.getString(R.string.manager_examined, score)
        if (hasInspected()) return R.string.manager_exam_un.resString()
        return R.string.manager_check_un.resString()
    }

    //学校拼接名称
    fun schoolStr(): String {
        val stu = examinee ?: return ""
        return APP.getString(R.string.manager_info, stu.schoolName, stu.schoolAge, stu.schoolClass)
    }

    //计划拼接名称
    fun planStr(): String {
        val stu = examinee ?: return ""
        return APP.getString(R.string.manager_info, stu.examPlanCode, stu.examAreaCode, stu.examSiteCode)
    }

    @Ignore
    constructor(examinee: Examinee, examProject: ExamProject) : this() {
        examineeId = examinee.id
        examPlanId = examinee.examPlanId
        examAreaId = examinee.examAreaId
        examSiteId = examinee.examSiteId
        projectId = examProject.id
        projectName = examProject.projectName
    }

    @Ignore
    constructor(parcel: Parcel) : this() {
        id = parcel.readInt()
        examineeId = parcel.readInt()
        projectId = parcel.readInt()
        projectName = parcel.readString()!!
        examPlanId = parcel.readInt()
        examAreaId = parcel.readInt()
        examSiteId = parcel.readInt()
        inspectStatus = parcel.readInt()
        examCount = parcel.readInt()
        lackStatus = parcel.readInt()
        score = parcel.readInt()
        sureTime = parcel.readLong()
        uploadStatus = parcel.readInt()
        lackUploadStatus = parcel.readInt()
        photoUploadStatus = parcel.readInt()
        examinee = parcel.readParcelable(Examinee::class.java.classLoader)
        inspectList = parcel.createTypedArrayList(ExamInspect.CREATOR)
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeInt(examineeId)
        parcel.writeInt(projectId)
        parcel.writeString(projectName)
        parcel.writeInt(examPlanId)
        parcel.writeInt(examAreaId)
        parcel.writeInt(examSiteId)
        parcel.writeInt(inspectStatus)
        parcel.writeInt(examCount)
        parcel.writeInt(lackStatus)
        parcel.writeInt(score)
        parcel.writeLong(sureTime)
        parcel.writeInt(uploadStatus)
        parcel.writeInt(lackUploadStatus)
        parcel.writeInt(photoUploadStatus)
        parcel.writeParcelable(examinee, flags)
        parcel.writeTypedList(inspectList)
    }

    override fun describeContents(): Int {
        return 0
    }

    override fun toString(): String {
        return "ExamResult(id=$id, examineeId=$examineeId, projectId=$projectId, projectName='$projectName', examPlanId=$examPlanId, examAreaId=$examAreaId, examSiteId=$examSiteId, inspectStatus=$inspectStatus, examCount=$examCount, lackStatus=$lackStatus, score=$score, sureTime=$sureTime, uploadStatus=$uploadStatus, lackUploadStatus=$lackUploadStatus, photoUploadStatus=$photoUploadStatus, examinee=$examinee, inspectList=$inspectList, isSelected=$isSelected)"
    }

    companion object CREATOR : Parcelable.Creator<ExamResult> {
        override fun createFromParcel(parcel: Parcel): ExamResult {
            return ExamResult(parcel)
        }

        override fun newArray(size: Int): Array<ExamResult?> {
            return arrayOfNulls(size)
        }
    }

    class ExamResultSerializer : JsonSerializer<ExamResult> {
        override fun serialize(src: ExamResult, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
            val json = JsonObject()
            json.addProperty("studentId", src.examineeId)
            json.addProperty("examAreaId", src.examAreaId)
            json.addProperty("examPlanId", src.examPlanId)
            json.addProperty("examSiteId", src.examSiteId)
            json.addProperty("examProjectId", src.projectId)

            //如果没有缺考带上成绩分数
            if (!src.isLack())
                json.addProperty("scorce", src.score)
            return json
        }
    }

}